#ifndef RANDOM_H
#define RANDOM_H

#include <cstdlib>
#include <ctime>
#include <cmath>
#include <climits>

typedef unsigned int uint32;
typedef int int32;


class Random
{
public:
    static const unsigned int MAX_RANDOM = UINT_MAX;

    // Constructors and Destructors
    Random();
    Random( unsigned int seedValue );
    Random( const Random &other );
    ~Random();

    Random &operator=( const Random &other );

    // Accessors
    unsigned int next(); // Calls initialize
    unsigned int next( unsigned int max );
    int next( int min, int max );

    double doubleNext();
    double doubleNext( double max );
    double doubleNext( double min, double max );

    double doubleNextGaussian();
    double doubleNextGaussian( double standardDeviation );
    double doubleNextGaussian( double mean, double standardDeviation );

    int nextGaussian();
    int nextGaussian( int standardDeviation );
    int nextGaussian( int mean, int standardDeviation );

    unsigned int initialSeed() const;
    void reset( unsigned int newSeed );
    void reset();

private:
    void initialize();
    void initialize( unsigned int newSeed );

    static unsigned int InitialSeed;
    static unsigned int CurrentSeed;
    static bool Initialized;
    static bool GaussianComputed;
    static double LastGaussian;

    // R250
    static unsigned int R250Index;
    static unsigned int R250Buffer[250];

    static unsigned int nextLCPNG();
};

#endif // #ifndef _RANDOM_HPP_

// implement - R250 - http://faculty.uml.edu/jpropp/r250.c
